package connection

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql" // 注意下划线，它会触发包的初始化，注册驱动
	"github.com/go-xorm/xorm"
	"github.com/spf13/viper"
	"sync"
)

type MysqlConfig struct {
	username string
	//连接数据库的密码
	password string
	//连接数据库的地址
	ip string
	//连接数据库的端口号
	port int
	//连接数据库的具体数据库名称
	dbname string
	//连接数据库的编码格式
	charset string
}

// db := pool.Get()
// defer db.Close()
type MySQLPool struct {
	pool      *sync.Pool
	connector func() (*sql.DB, error)
}

// db := pool.Get()
// defer db.Close()
type OrmPool struct {
	pool      *sync.Pool
	connector func() (*xorm.Engine, error)
}

func (p *OrmPool) Get() *xorm.Engine {
	return p.pool.Get().(*xorm.Engine)
}
func (p *OrmPool) Put(db *xorm.Engine) {
	p.pool.Put(db)
}
func GetXorm() (*xorm.Engine, error) {
	return xorm.NewEngine("mysql", getDbUrl())
}
func (p *MySQLPool) Get() *sql.DB {
	return p.pool.Get().(*sql.DB)
}
func (p *MySQLPool) Put(db *sql.DB) {
	p.pool.Put(db)
}

func NewMySQLPool(connector func() (*sql.DB, error)) *MySQLPool {
	return &MySQLPool{
		pool: &sync.Pool{
			New: func() interface{} {
				db, err := connector()
				if err != nil {
					panic(err)
				}
				return db
			},
		},
		connector: connector,
	}
}
func mysqlConf() *MysqlConfig {
	return &MysqlConfig{
		username: viper.GetString("db.mysql.conf.username"),
		//连接数据库的密码
		password: viper.GetString("db.mysql.conf.password"),
		//连接数据库的地址
		ip: viper.GetString("db.mysql.conf.ip"),
		//连接数据库的端口号
		port: viper.GetInt("db.mysql.conf.port"),
		//连接数据库的具体数据库名称
		dbname: viper.GetString("db.mysql.conf.dbname"),
		//连接数据库的编码格式
		charset: viper.GetString("db.mysql.conf.charset"),
	}
}
func getDbUrl() string {
	conf := mysqlConf()
	return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s", conf.username, conf.password, conf.ip, conf.port, conf.dbname, conf.charset)
}

func Db() *MySQLPool {

	pool := NewMySQLPool(func() (*sql.DB, error) {
		//user := conf.username
		//pass := conf.password
		//dbname := conf.dbname
		//port := strconv.Itoa(conf.port)
		//ip := conf.ip
		//mysqlUrl := user + ":" + pass + "@tcp(" + ip + ":" + port + ")/" + dbname
		//mysqlUrl := getDbUrl()
		return sql.Open("mysql", getDbUrl())
	})
	//db.Get().Close()
	//defer db.Close()
	return pool
}
func test() {
	db := Db()
	conn := db.Get()
	//用完 放进池中 给别的线程可以调用，
	db.Put(conn)
	//或者直接关闭回收 不给put到池中共享
	defer conn.Close()
}
func testXorm() {
	//db, _ :=GetXorm()
	//db.Where()
}
